<!DOCTYPE html>

<html>
    <head>
        <meta charset="UTF-8">
        <title>call</title>
        <script type="text/javascript">
            // 采用"函数声明"方式定义函数
            function welcome(nickname){
                console.log(`热烈欢迎${nickname}来到开发喵`);
            }

            // 通过函数名来调用函数
            welcome( '阿芳' );

            // 通过 call 来调用函数
            // Function.prototype.call( thisArg [, ...params ] )
            welcome.call( null, '小芳' );

            console.log( '- '.repeat(20) );

            // 在浏览器中 globalThis 指向 window
            globalThis.name = '李小芳';

            function introduce(){
                console.log( this === globalThis );
                console.log(`大家好，我是${this.name}`);
            }

            // 直接用函数名调用函数时，函数内部的 `this` 指向 `global object`
            introduce();
            // 通过call调用函数时，若call首个参数为 null 或 undefined 或 未显式指定，
            // 则函数内部的 `this` 指向 `global object`
            introduce.call( null );
            introduce.call( undefined );
            introduce.call();

            const x = { name: '赵德芳' }
            // 将 x 作为参数传递给 call 函数，
            // 则在调用 introduce 函数时，其内部的 this 就指向了 x 对应的实例
            introduce.call( x );

            console.log( '- '.repeat(20) );

            const instance = {
                name: '菲尔娜',
                fly(){
                    console.log( this === instance );
                    console.log(`${this.name}飞起来了`);
                }
            }

            // 通过定义方法的实例调用方法时，方法内部的this指向定义该方法的实例
            instance.fly();

            // 通过 call 调用 instance.fly 方法时，
            // 为 call 函数传入的第一个参数就是 instance.fly 方法内部this指向的实例
            instance.fly.call(x);

        </script>
    </head>
    <body>
        <h3>Function.prototype.call( thisArg, ...params )</h3>
        <p>请在浏览器终端中查看运行结果</p>
    </body>
</html>